{
 "nbformat": 4,
 "nbformat_minor": 2,
 "metadata": {
  "language_info": {
   "name": "python",
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "version": "3.7.4-final"
  },
  "orig_nbformat": 2,
  "file_extension": ".py",
  "mimetype": "text/x-python",
  "name": "python",
  "npconvert_exporter": "python",
  "pygments_lexer": "ipython3",
  "version": 3,
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3"
  }
 },
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "#!/usr/bin/env python3\n",
    "import numpy as np\n",
    "samples_and = [\n",
    "    [0, 0, 0],\n",
    "    [1, 0, 0],\n",
    "    [0, 1, 0],\n",
    "    [1, 1, 1],\n",
    "]\n",
    "\n",
    "samples_or = [\n",
    "    [0, 0, 0],\n",
    "    [1, 0, 1],\n",
    "    [0, 1, 1],\n",
    "    [1, 1, 1],\n",
    "]\n",
    "\n",
    "samples_xor = [\n",
    "    [0, 0, 0],\n",
    "    [1, 0, 1],\n",
    "    [0, 1, 1],\n",
    "    [1, 1, 0],\n",
    "]\n",
    "\n",
    "\n",
    "def perceptron(samples, w, b, a):\n",
    "    for i in range(10):\n",
    "        for j in range(4):\n",
    "            x = np.array(samples[j][:2])\n",
    "            y = 1 if np.dot(w, x) + b > 0 else 0\n",
    "            d = np.array(samples[j][2])\n",
    "            delta_b = a*(d-y)\n",
    "            delta_w = a*(d-y)*x\n",
    "            print('epoch {} sample {}  [{} {} {} {} {} {} {}]'.format(\n",
    "                i, j, w[0], w[1], b, y, delta_w[0], delta_w[1], delta_b\n",
    "            ))\n",
    "            w = w + delta_w\n",
    "            b = b + delta_b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": "logical and 1\nepoch 0 sample 0  [1 2 0 0 0 0 0]\nepoch 0 sample 1  [1 2 0 1 -1 0 -1]\nepoch 0 sample 2  [0 2 -1 1 0 -1 -1]\nepoch 0 sample 3  [0 1 -2 0 1 1 1]\nepoch 1 sample 0  [1 2 -1 0 0 0 0]\nepoch 1 sample 1  [1 2 -1 0 0 0 0]\nepoch 1 sample 2  [1 2 -1 1 0 -1 -1]\nepoch 1 sample 3  [1 1 -2 0 1 1 1]\nepoch 2 sample 0  [2 2 -1 0 0 0 0]\nepoch 2 sample 1  [2 2 -1 1 -1 0 -1]\nepoch 2 sample 2  [1 2 -2 0 0 0 0]\nepoch 2 sample 3  [1 2 -2 1 0 0 0]\nepoch 3 sample 0  [1 2 -2 0 0 0 0]\nepoch 3 sample 1  [1 2 -2 0 0 0 0]\nepoch 3 sample 2  [1 2 -2 0 0 0 0]\nepoch 3 sample 3  [1 2 -2 1 0 0 0]\nepoch 4 sample 0  [1 2 -2 0 0 0 0]\nepoch 4 sample 1  [1 2 -2 0 0 0 0]\nepoch 4 sample 2  [1 2 -2 0 0 0 0]\nepoch 4 sample 3  [1 2 -2 1 0 0 0]\nepoch 5 sample 0  [1 2 -2 0 0 0 0]\nepoch 5 sample 1  [1 2 -2 0 0 0 0]\nepoch 5 sample 2  [1 2 -2 0 0 0 0]\nepoch 5 sample 3  [1 2 -2 1 0 0 0]\nepoch 6 sample 0  [1 2 -2 0 0 0 0]\nepoch 6 sample 1  [1 2 -2 0 0 0 0]\nepoch 6 sample 2  [1 2 -2 0 0 0 0]\nepoch 6 sample 3  [1 2 -2 1 0 0 0]\nepoch 7 sample 0  [1 2 -2 0 0 0 0]\nepoch 7 sample 1  [1 2 -2 0 0 0 0]\nepoch 7 sample 2  [1 2 -2 0 0 0 0]\nepoch 7 sample 3  [1 2 -2 1 0 0 0]\nepoch 8 sample 0  [1 2 -2 0 0 0 0]\nepoch 8 sample 1  [1 2 -2 0 0 0 0]\nepoch 8 sample 2  [1 2 -2 0 0 0 0]\nepoch 8 sample 3  [1 2 -2 1 0 0 0]\nepoch 9 sample 0  [1 2 -2 0 0 0 0]\nepoch 9 sample 1  [1 2 -2 0 0 0 0]\nepoch 9 sample 2  [1 2 -2 0 0 0 0]\nepoch 9 sample 3  [1 2 -2 1 0 0 0]\nlogical and 2\nepoch 0 sample 0  [-1 1 0 0 0 0 0]\nepoch 0 sample 1  [-1 1 0 0 0 0 0]\nepoch 0 sample 2  [-1 1 0 1 0 -1 -1]\nepoch 0 sample 3  [-1 0 -1 0 1 1 1]\nepoch 1 sample 0  [0 1 0 0 0 0 0]\nepoch 1 sample 1  [0 1 0 0 0 0 0]\nepoch 1 sample 2  [0 1 0 1 0 -1 -1]\nepoch 1 sample 3  [0 0 -1 0 1 1 1]\nepoch 2 sample 0  [1 1 0 0 0 0 0]\nepoch 2 sample 1  [1 1 0 1 -1 0 -1]\nepoch 2 sample 2  [0 1 -1 0 0 0 0]\nepoch 2 sample 3  [0 1 -1 0 1 1 1]\nepoch 3 sample 0  [1 2 0 0 0 0 0]\nepoch 3 sample 1  [1 2 0 1 -1 0 -1]\nepoch 3 sample 2  [0 2 -1 1 0 -1 -1]\nepoch 3 sample 3  [0 1 -2 0 1 1 1]\nepoch 4 sample 0  [1 2 -1 0 0 0 0]\nepoch 4 sample 1  [1 2 -1 0 0 0 0]\nepoch 4 sample 2  [1 2 -1 1 0 -1 -1]\nepoch 4 sample 3  [1 1 -2 0 1 1 1]\nepoch 5 sample 0  [2 2 -1 0 0 0 0]\nepoch 5 sample 1  [2 2 -1 1 -1 0 -1]\nepoch 5 sample 2  [1 2 -2 0 0 0 0]\nepoch 5 sample 3  [1 2 -2 1 0 0 0]\nepoch 6 sample 0  [1 2 -2 0 0 0 0]\nepoch 6 sample 1  [1 2 -2 0 0 0 0]\nepoch 6 sample 2  [1 2 -2 0 0 0 0]\nepoch 6 sample 3  [1 2 -2 1 0 0 0]\nepoch 7 sample 0  [1 2 -2 0 0 0 0]\nepoch 7 sample 1  [1 2 -2 0 0 0 0]\nepoch 7 sample 2  [1 2 -2 0 0 0 0]\nepoch 7 sample 3  [1 2 -2 1 0 0 0]\nepoch 8 sample 0  [1 2 -2 0 0 0 0]\nepoch 8 sample 1  [1 2 -2 0 0 0 0]\nepoch 8 sample 2  [1 2 -2 0 0 0 0]\nepoch 8 sample 3  [1 2 -2 1 0 0 0]\nepoch 9 sample 0  [1 2 -2 0 0 0 0]\nepoch 9 sample 1  [1 2 -2 0 0 0 0]\nepoch 9 sample 2  [1 2 -2 0 0 0 0]\nepoch 9 sample 3  [1 2 -2 1 0 0 0]\nlogical and 3\nepoch 0 sample 0  [1 2 2 1 0 0 -1]\nepoch 0 sample 1  [1 2 1 1 -1 0 -1]\nepoch 0 sample 2  [0 2 0 1 0 -1 -1]\nepoch 0 sample 3  [0 1 -1 0 1 1 1]\nepoch 1 sample 0  [1 2 0 0 0 0 0]\nepoch 1 sample 1  [1 2 0 1 -1 0 -1]\nepoch 1 sample 2  [0 2 -1 1 0 -1 -1]\nepoch 1 sample 3  [0 1 -2 0 1 1 1]\nepoch 2 sample 0  [1 2 -1 0 0 0 0]\nepoch 2 sample 1  [1 2 -1 0 0 0 0]\nepoch 2 sample 2  [1 2 -1 1 0 -1 -1]\nepoch 2 sample 3  [1 1 -2 0 1 1 1]\nepoch 3 sample 0  [2 2 -1 0 0 0 0]\nepoch 3 sample 1  [2 2 -1 1 -1 0 -1]\nepoch 3 sample 2  [1 2 -2 0 0 0 0]\nepoch 3 sample 3  [1 2 -2 1 0 0 0]\nepoch 4 sample 0  [1 2 -2 0 0 0 0]\nepoch 4 sample 1  [1 2 -2 0 0 0 0]\nepoch 4 sample 2  [1 2 -2 0 0 0 0]\nepoch 4 sample 3  [1 2 -2 1 0 0 0]\nepoch 5 sample 0  [1 2 -2 0 0 0 0]\nepoch 5 sample 1  [1 2 -2 0 0 0 0]\nepoch 5 sample 2  [1 2 -2 0 0 0 0]\nepoch 5 sample 3  [1 2 -2 1 0 0 0]\nepoch 6 sample 0  [1 2 -2 0 0 0 0]\nepoch 6 sample 1  [1 2 -2 0 0 0 0]\nepoch 6 sample 2  [1 2 -2 0 0 0 0]\nepoch 6 sample 3  [1 2 -2 1 0 0 0]\nepoch 7 sample 0  [1 2 -2 0 0 0 0]\nepoch 7 sample 1  [1 2 -2 0 0 0 0]\nepoch 7 sample 2  [1 2 -2 0 0 0 0]\nepoch 7 sample 3  [1 2 -2 1 0 0 0]\nepoch 8 sample 0  [1 2 -2 0 0 0 0]\nepoch 8 sample 1  [1 2 -2 0 0 0 0]\nepoch 8 sample 2  [1 2 -2 0 0 0 0]\nepoch 8 sample 3  [1 2 -2 1 0 0 0]\nepoch 9 sample 0  [1 2 -2 0 0 0 0]\nepoch 9 sample 1  [1 2 -2 0 0 0 0]\nepoch 9 sample 2  [1 2 -2 0 0 0 0]\nepoch 9 sample 3  [1 2 -2 1 0 0 0]\n"
    }
   ],
   "source": [
    "# 逻辑与\n",
    "print('logical and 1')\n",
    "perceptron(samples_and, np.array([1,2]), 0, 1)\n",
    "#  观察不同的初始w,b,a\n",
    "print('logical and 2')\n",
    "perceptron(samples_and, np.array([-1,1]), 0, 1)\n",
    "print('logical and 3')\n",
    "perceptron(samples_and, np.array([1,2]), 2, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将函数改为初始值传递进去\n",
    "使用初始值w=[1,2] b=0 a=1和使用初始值w=[-1,1] b=0 a=1 、w=[1,2] b=2 a=1\n",
    "最终训练结果都是w=[1,2] b=-2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": "logical or\nepoch 0 sample 0  [1 2 0 0 0 0 0]\nepoch 0 sample 1  [1 2 0 1 0 0 0]\nepoch 0 sample 2  [1 2 0 1 0 0 0]\nepoch 0 sample 3  [1 2 0 1 0 0 0]\nepoch 1 sample 0  [1 2 0 0 0 0 0]\nepoch 1 sample 1  [1 2 0 1 0 0 0]\nepoch 1 sample 2  [1 2 0 1 0 0 0]\nepoch 1 sample 3  [1 2 0 1 0 0 0]\nepoch 2 sample 0  [1 2 0 0 0 0 0]\nepoch 2 sample 1  [1 2 0 1 0 0 0]\nepoch 2 sample 2  [1 2 0 1 0 0 0]\nepoch 2 sample 3  [1 2 0 1 0 0 0]\nepoch 3 sample 0  [1 2 0 0 0 0 0]\nepoch 3 sample 1  [1 2 0 1 0 0 0]\nepoch 3 sample 2  [1 2 0 1 0 0 0]\nepoch 3 sample 3  [1 2 0 1 0 0 0]\nepoch 4 sample 0  [1 2 0 0 0 0 0]\nepoch 4 sample 1  [1 2 0 1 0 0 0]\nepoch 4 sample 2  [1 2 0 1 0 0 0]\nepoch 4 sample 3  [1 2 0 1 0 0 0]\nepoch 5 sample 0  [1 2 0 0 0 0 0]\nepoch 5 sample 1  [1 2 0 1 0 0 0]\nepoch 5 sample 2  [1 2 0 1 0 0 0]\nepoch 5 sample 3  [1 2 0 1 0 0 0]\nepoch 6 sample 0  [1 2 0 0 0 0 0]\nepoch 6 sample 1  [1 2 0 1 0 0 0]\nepoch 6 sample 2  [1 2 0 1 0 0 0]\nepoch 6 sample 3  [1 2 0 1 0 0 0]\nepoch 7 sample 0  [1 2 0 0 0 0 0]\nepoch 7 sample 1  [1 2 0 1 0 0 0]\nepoch 7 sample 2  [1 2 0 1 0 0 0]\nepoch 7 sample 3  [1 2 0 1 0 0 0]\nepoch 8 sample 0  [1 2 0 0 0 0 0]\nepoch 8 sample 1  [1 2 0 1 0 0 0]\nepoch 8 sample 2  [1 2 0 1 0 0 0]\nepoch 8 sample 3  [1 2 0 1 0 0 0]\nepoch 9 sample 0  [1 2 0 0 0 0 0]\nepoch 9 sample 1  [1 2 0 1 0 0 0]\nepoch 9 sample 2  [1 2 0 1 0 0 0]\nepoch 9 sample 3  [1 2 0 1 0 0 0]\n"
    }
   ],
   "source": [
    "# 逻辑或\n",
    "print('logical or')\n",
    "perceptron(samples_or, np.array([1,2]), 0, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": "logical xor\nepoch 0 sample 0  [1 2 0 0 0 0 0]\nepoch 0 sample 1  [1 2 0 1 0 0 0]\nepoch 0 sample 2  [1 2 0 1 0 0 0]\nepoch 0 sample 3  [1 2 0 1 -1 -1 -1]\nepoch 1 sample 0  [0 1 -1 0 0 0 0]\nepoch 1 sample 1  [0 1 -1 0 1 0 1]\nepoch 1 sample 2  [1 1 0 1 0 0 0]\nepoch 1 sample 3  [1 1 0 1 -1 -1 -1]\nepoch 2 sample 0  [0 0 -1 0 0 0 0]\nepoch 2 sample 1  [0 0 -1 0 1 0 1]\nepoch 2 sample 2  [1 0 0 0 0 1 1]\nepoch 2 sample 3  [1 1 1 1 -1 -1 -1]\nepoch 3 sample 0  [0 0 0 0 0 0 0]\nepoch 3 sample 1  [0 0 0 0 1 0 1]\nepoch 3 sample 2  [1 0 1 1 0 0 0]\nepoch 3 sample 3  [1 0 1 1 -1 -1 -1]\nepoch 4 sample 0  [0 -1 0 0 0 0 0]\nepoch 4 sample 1  [0 -1 0 0 1 0 1]\nepoch 4 sample 2  [1 -1 1 0 0 1 1]\nepoch 4 sample 3  [1 0 2 1 -1 -1 -1]\nepoch 5 sample 0  [0 -1 1 1 0 0 -1]\nepoch 5 sample 1  [0 -1 0 0 1 0 1]\nepoch 5 sample 2  [1 -1 1 0 0 1 1]\nepoch 5 sample 3  [1 0 2 1 -1 -1 -1]\nepoch 6 sample 0  [0 -1 1 1 0 0 -1]\nepoch 6 sample 1  [0 -1 0 0 1 0 1]\nepoch 6 sample 2  [1 -1 1 0 0 1 1]\nepoch 6 sample 3  [1 0 2 1 -1 -1 -1]\nepoch 7 sample 0  [0 -1 1 1 0 0 -1]\nepoch 7 sample 1  [0 -1 0 0 1 0 1]\nepoch 7 sample 2  [1 -1 1 0 0 1 1]\nepoch 7 sample 3  [1 0 2 1 -1 -1 -1]\nepoch 8 sample 0  [0 -1 1 1 0 0 -1]\nepoch 8 sample 1  [0 -1 0 0 1 0 1]\nepoch 8 sample 2  [1 -1 1 0 0 1 1]\nepoch 8 sample 3  [1 0 2 1 -1 -1 -1]\nepoch 9 sample 0  [0 -1 1 1 0 0 -1]\nepoch 9 sample 1  [0 -1 0 0 1 0 1]\nepoch 9 sample 2  [1 -1 1 0 0 1 1]\nepoch 9 sample 3  [1 0 2 1 -1 -1 -1]\n"
    }
   ],
   "source": [
    "# 逻辑异或\n",
    "print('logical xor')\n",
    "perceptron(samples_xor, np.array([1,2]), 0, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![title](img.webp)<br>\n",
    "第二题<br>\n",
    "无法解决异或问题，是因为感知机的阶跃函数只是简单的线性关系，而异或并非线性的。如上图，\n",
    "感知机无法通过线性函数将其分成两类。"
   ]
  }
 ]
}